/*
  (C) 2007 - Boston University
  Contact: Michael Ocean 

	This class is taken directly from a CS511 submission

  This work is a part of the larger snBench project.  Information
  can be found at: http://csr.bu.edu/snbench 

  This program is free software; you can redistribute it and/or
  modify it under the terms of Version 2 of the GNU General Public 
  License.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package stepide.opcodes;

import java.io.Serializable;

/**
 * Overview: The OpcodeStruct holds all of the information related to a single STEP opcode,
 * as defined by the opcode xsd schema contained in the same directory of this
 * class file.
 */

public class Opcode implements Serializable {
	private String fqn;
	private String opcodeName;
	private String snafu;
	private String description;
	private boolean overloaded;
	private TypeSignature[] types;
	private static final long serialVersionUID = 4252007L;
	
	/**
	 * Constructs an Opcode that contains all of the info on a specific STEP opcode
	 * @param opcodeName name of the STEP opcode
	 * @param fqn The fully qualified name of an opcode, including it's location in the class hierarchy.  Example: sxe.core.math.add
	 * @param snafu name of the corresponing SNAFU function
	 * @param description text description of what the opcode does
	 * @param overloaded true if the opcode can have different sets of input/output types
	 * @param types a TypeSignature object that contains all of the snBench type information on the opcode
	 * @exception  IllegalArgumentException  if any of the String objects are null or are of length < 1
	 */
	Opcode(String opcodeName, String fqn, String snafu, String description, boolean overloaded, TypeSignature[] types) {
		if( (opcodeName == null) || (fqn == null) || (snafu == null) || (description == null) || (types == null)) {	
			throw new IllegalArgumentException("An input param is null");
		}
		else if( (opcodeName.length() < 1) || (fqn.length() < 1 ) || (snafu.length() < 1) || (description.length() < 1)) {	
			throw new IllegalArgumentException("An input String has a length less than 1");
		}
		
		this.opcodeName = opcodeName;
		this.fqn = fqn;
		this.snafu = snafu;
		this.description = description;
		this.overloaded = overloaded;
		this.types = types;
	}
	
	/**
	 * @return the fully qualified name (including location in class hierarchy) of the opcode
	 */
	public String getFqn() { return fqn; }
	
	/**
	 * @return the name of the STEP opcode
	 */
	public String getOpcodeName() { return opcodeName; }
	
	/**
	 * @return the name of the corresponging SNAFU function name
	 */
	public String getSnafu() { return snafu; }
	
	/**
	 * @return the text description of what this opcode does
	 */
	public String getDescription() { return description; }
	
	/**
	 * @return true if the opcode has multipe input/output type parameters
	 */
	public boolean isOverloaded() { return overloaded; }
	
	/**
	 * @return a TypeSignature object representing all of the input and output types this opcode supports, including overloading
	 */
	public TypeSignature[] getTypeSignatures() { return types; }
	
	/**
	 * @return A string representation of all type opcode information
	 */
	public String toString() {
		String typeSigInfo = "";
		for(int i = 0; i < getTypeSignatures().length; i++) {
			typeSigInfo += getTypeSignatures()[i].toString();
		}

		String s = "<b>Fully Qualified Name</b>: "  + getFqn() + "\n" + 
			"<b>Opcode Name:</b> " + getOpcodeName() + "\n" +
			"<b>Corresponding Snafu Function:</b> " + getSnafu() + "\n" +
			"<b>Description:</b><i>" + getDescription() + "\n</i>" +
			"<b>Is Overloaded:</b> " + ((Boolean)isOverloaded()).toString() + "\n" +
			typeSigInfo;
		
		return "<html>" + s.replace("\n", "<br>") + "</html>";
	}
}
